home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / hf^k-1.dms / in.adf / Examples.Lha / Parser / Parser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-18  |  5.4 KB  |  351 lines

  1.  
  2. #ifndef    PARSER_C
  3. #define    PARSER_C
  4.  
  5. //    Short:        Command line parser for mathematical expressions.
  6. //    Version:        $VER: Parser.c 1.0 (16.01.96)
  7. //    Copyright:    Copyright © 1996 Constantin Rack. All rights reserved.
  8.  
  9.  
  10. //    ========================================================= INCLUDES
  11.  
  12. #include    <ctype.h>                            //    Needed for isdigit()
  13. #include    <iostream.h>                        //    Needed for standard I/O
  14. #include    <string.h>                            //    Needed for string functions
  15.  
  16.  
  17. //    ========================================================== DEFINES
  18.  
  19. enum    Consts                                    //    Some constant values
  20. {
  21.     FALSE        =    0,
  22.     TRUE        =    1,
  23.     Op_Num    =    5,                                //    Number of operators
  24. };
  25.  
  26. enum    OperatorTypes
  27. {
  28.     Op_Err    =    -1,                            //    Bad operator
  29.     Op_Add    =    0,                                //    +
  30.     Op_Sub    =    1,                                //    -
  31.     Op_Mul    =    2,                                //    *
  32.     Op_Div    =    3,                                //    /
  33. };
  34.  
  35. struct    Operator
  36. {
  37.     int    op_Type;                                //    Type of operator (see above)
  38.     char*    op_Name;                                //    Operator as a string
  39. };
  40.  
  41.  
  42. //    ======================================================== VARIABLES
  43.  
  44. const char*    Version    =    "$VER: Parser 1.0 (16.01.96)";
  45. char*            ActPtr    =    0;                    //    Actual text pointer
  46. int            Error        =    FALSE;            //    Error indicator
  47.  
  48. struct    Operator    operators[Op_Num]    =
  49. {
  50.     {
  51.         Op_Add,    "+"
  52.     },
  53.     
  54.     {
  55.         Op_Sub,    "-"
  56.     },
  57.     
  58.     {
  59.         Op_Mul,    "*"
  60.     },
  61.     
  62.     {
  63.         Op_Div,    "/"
  64.     },
  65. };            
  66.  
  67.  
  68. //    ======================================================= PROTOTYPES
  69.  
  70. long    Expression();
  71. long    Factor();
  72. long    Constant();
  73. long    Operater(); 
  74.  
  75.  
  76. //    ======================================================== FUNCTIONS
  77.  
  78.  
  79. //    --------------------------------------------------------- FUNCTION
  80. //    Operater()
  81. //
  82. //    Short:    Reads an operator and returns its value.
  83. //    Needs:    ctype.h, string.h
  84.  
  85. long    Operater()
  86. {
  87.     long    result    =    0;
  88.     long    i            =    0;
  89.     char*    string    =    0;
  90.     
  91.     string    =    new char [80];
  92.     result    =    Op_Err;
  93.             
  94.     if( string == 0 )
  95.     {
  96.         return    result;
  97.     }
  98.     
  99.     while( *ActPtr != ' ' && i < 79 )
  100.     {
  101.         string[i++]    =    tolower( *ActPtr++ );
  102.     }
  103.  
  104.     ActPtr++;
  105.  
  106.     string[i]    =    '\0';
  107.  
  108.     for(i=0;i<Op_Num;i++)
  109.     {
  110.         if( strcmp(operators[i].op_Name,string) == 0 )
  111.         {
  112.             result    =    operators[i].op_Type;
  113.         }
  114.     }
  115.  
  116.     delete    []    string;
  117.  
  118.     return result;
  119. }
  120.  
  121.  
  122. //    --------------------------------------------------------- FUNCTION
  123. //    Constant()
  124. //
  125. //    Short:    Reads a constant number ("C-Tools", ISBN 3-89090-190-5)
  126. //    Needs:    ctype.h
  127.  
  128. long    Constant()
  129. {
  130.     long    result    =    0;
  131.  
  132.     while( *ActPtr != 0 && isdigit(*ActPtr) != 0 )
  133.     {
  134.         result    =    (result * 10) + (*ActPtr++ - '0');
  135.     }
  136.  
  137.     return result;
  138. }
  139.  
  140. //    --------------------------------------------------------- FUNCTION
  141. //    Factor()
  142. //
  143. //    Short:    Evaluates an expression. This function is recursive.
  144. //    Needs:    ctype.h
  145.  
  146. long    Factor()
  147. {
  148.     long    result    =    0;
  149.     long    sign        =    1;
  150.  
  151.     if( *ActPtr == 0 )
  152.     {
  153.         return result;
  154.     }
  155.         
  156.  
  157.     if( *ActPtr == '-' )
  158.     {
  159.         sign    =    -1;
  160.         ActPtr++;
  161.     }
  162.  
  163.     if( isdigit( *ActPtr ) != 0 )
  164.     {
  165.         result    =    Constant();
  166.     }
  167.     else
  168.     {
  169.         if( *ActPtr == '(' )
  170.         {
  171.             result    =    Expression();
  172.         }
  173.     }
  174.  
  175.     result    *=    sign;
  176.  
  177.     return    result;
  178. }
  179.  
  180. //    --------------------------------------------------------- FUNCTION
  181. //    Expression()
  182. //
  183. //    Short:    Evaluates a bracket expression.
  184. //    Needs:    stream.h
  185.  
  186. long    Expression()
  187. {
  188.     long    result    =    0;
  189.     long    op            =    0;
  190.  
  191.     if( *ActPtr == '(' )
  192.     {
  193.         ActPtr++;
  194.  
  195.         op                =    Operater();
  196.         result        =    Factor();
  197.  
  198.         switch( op )
  199.         {
  200.             case    Op_Add:
  201.                     {
  202.                         while( *ActPtr++ != ')' )
  203.                         {
  204.                             result    +=    Factor();
  205.                         }
  206.                     }        
  207.                     break;    
  208.                     
  209.             case    Op_Sub:
  210.                     {
  211.                         while( *ActPtr++ != ')' )
  212.                         {
  213.                             result    -=    Factor();
  214.                         }
  215.                     }        
  216.                     break;    
  217.                     
  218.             case    Op_Mul:
  219.                     {
  220.                         while( *ActPtr++ != ')' )
  221.                         {
  222.                             result    *=    Factor();
  223.                         }
  224.                     }        
  225.                     break;    
  226.                     
  227.             case    Op_Div:
  228.                     {
  229.                         long    temp    =    0;
  230.                         
  231.                         while( *ActPtr++ != ')' )
  232.                         {
  233.                             temp    =    Factor();
  234.                             
  235.                             if( temp != 0 )
  236.                             {
  237.                                 result    /=    temp;
  238.                             }
  239.                             else
  240.                             {
  241.                                 cerr    <<    "** Division by zero\n";
  242.                                 Error    =    TRUE;
  243.                             }        
  244.                         }
  245.                     }        
  246.                     break;    
  247.                     
  248.             case    Op_Err:
  249.             default:
  250.                 {
  251.                         cerr    <<    "** Bad operator\n";
  252.                         Error    =    TRUE;
  253.                     }
  254.                     break;    
  255.         }
  256.     }
  257.     else
  258.     {
  259.         if( *ActPtr == '?' )
  260.         {
  261.             cerr    <<    "This parser uses a simple praefix notation. Example:\n"
  262.                     <<    "\t(+ 1 (* 2 (/ 10 5)))\n"
  263.                     <<    "would have the result 5. So always write the operator "
  264.                     <<    "first. Parser knows the following operators by now:\n";
  265.                     
  266.             {
  267.                 int    i    =    0;
  268.                 
  269.                 for(i=0;i<Op_Num;i++)
  270.                 {
  271.                     cerr    <<    operators[i].op_Name
  272.                             <<    ", ";
  273.                 }
  274.                 
  275.                 cerr    <<    "\n";
  276.             }
  277.             
  278.             cerr    <<    "\nCopyright © 1996 Constantin Rack. All rights reserved.\n";
  279.                     
  280.             Error    =    TRUE;
  281.         }
  282.         else
  283.         {
  284.             cerr    <<    "** Bad command line\n";
  285.             Error    =    TRUE;
  286.         }
  287.     }        
  288.  
  289.     return    result;
  290. }
  291.  
  292. //    --------------------------------------------------------- FUNCTION
  293. //    main()
  294. //
  295. //    Short:    Main function of the parser.
  296. //    Needs:    stream.h, string.h
  297.  
  298. int    main()
  299. {
  300.     int    okay        =    TRUE;
  301.     long    result    =    0;
  302.     char*    input        =    0;
  303.  
  304.     input    =    new char [256];
  305.     
  306.     if( input == 0 )
  307.     {
  308.         cerr    <<    "** Memory problem\n";
  309.         return    5;
  310.     }        
  311.  
  312.     cout    <<    "Parser 1.0 (16.01.96)\n"
  313.             <<    "Short:    Command line parser for mathematical expressions\n"
  314.             <<    "Usage:    Press '?' for more information\n\n";
  315.  
  316.     while( okay )
  317.     {
  318.         cout    <<    "Expression: ";
  319.         cin.getline(input,255);
  320.  
  321.         okay    =    strlen(input);
  322.         
  323.         if( okay > 0 )
  324.         {    
  325.             ActPtr    =    &input[0];
  326.             result    =    Expression();
  327.  
  328.             if( Error == 0 )
  329.             {
  330.                 cout    <<    "Result: "
  331.                         <<    result
  332.                         <<    "\n";
  333.             }
  334.             else
  335.             {
  336.                 Error    =    FALSE;
  337.             }
  338.         }    
  339.         else
  340.         {
  341.             cout    <<    "** Parser ended\n";
  342.         }
  343.     }
  344.     
  345.     delete    []    input;
  346.     
  347.     return    0;
  348. }
  349.  
  350. #endif    //    PARSER_C
  351.